package fons.model.query.fun;

public class FoldLeftFun implements Function {
	private final Function foldingFunction;
	private final Function initialValue;
	private final ListFun list;
	
	public FoldLeftFun() {
		this(null);
	}
	
	public FoldLeftFun(Function foldingFunction) {
		this(foldingFunction, null);
	}
	
	public FoldLeftFun(Function foldingFunction, Function initialValue) {
		this(foldingFunction, initialValue, null);
	}
	
	public FoldLeftFun(Function foldingFunction, Function initialValue, ListFun list) {
		this.list = list;
		this.initialValue = initialValue;
		this.foldingFunction = foldingFunction;
	}

	@Override
	public Function apply(Function other) {
		if (foldingFunction == null) return new FoldLeftFun(other);
		if (initialValue == null) return new FoldLeftFun(foldingFunction, other);
		if (list == null) {
			return new FoldLeftFun(foldingFunction, initialValue, (ListFun) other.apply());
		}
		
		throw new IllegalArgumentException("fold can only be used on lists!");
	}

	@Override
	public Function apply() {
		Number current = (Number) initialValue.apply();
		for (Function fun: list.get()) {
			current = (Number) foldingFunction.apply(current).apply(fun.apply()).apply();
		}
		return current;
	}

}
